package com.koron.order.experiment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.koron.bean.base.Attachment;
import com.koron.bean.base.Response;
import com.koron.bean.electronicSignature.ElectronicSignatureStatus;
import com.koron.bean.standard.deviceClasssify.dto.BaseTypeDTO;
import com.koron.bean.standard.deviceClasssify.po.TypeGroupParams;
import com.koron.bean.standard.deviceClasssify.po.TypeParams;
import com.koron.bean.standard.jobStock.experiment.dto.ExperimentDTO;
import com.koron.bean.standard.jobStock.experiment.dto.ExperimentItemDTO;
import com.koron.bean.standard.jobStock.experiment.po.ExperimentItemParams;
import com.koron.bean.standard.jobStock.experiment.po.ExperimentParams;
import com.koron.bean.system.org.OrgBean;
import com.koron.common.core.business.common.service.AttachmentService;
import com.koron.common.core.business.configsettings.bean.ConfigDetail;
import com.koron.common.core.business.configsettings.service.ConfigDetailService;
import com.koron.common.core.business.workflow.templates.WorkFlowHandler;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.OrgCacheUtils;
import com.koron.order.common.bean.po.*;
import com.koron.order.common.service.*;
import com.koron.order.common.tools.CommonCodeTools;
import com.koron.order.common.util.DateUtils;
import com.koron.order.experiment.bean.convertor.ExperimentConvertor;
import com.koron.order.experiment.bean.dto.ExperimentExecuteDto;
import com.koron.order.experiment.bean.dto.FiledDescriptDto;
import com.koron.order.experiment.bean.dto.KeyName;
import com.koron.order.experiment.bean.po.*;
import com.koron.order.experiment.bean.vo.ExperimentEquipmentVo;
import com.koron.order.experiment.bean.vo.ExperimentExecuteInfoVo;
import com.koron.order.experiment.bean.vo.ExperimentItemVo;
import com.koron.order.experiment.bean.vo.OperateFormVo;
import com.koron.order.experiment.feign.ElectronicSignatureFeignService;
import com.koron.order.experiment.feign.ExperimentEquipmentFeignService;
import com.koron.order.experiment.feign.ExperimentStandFeignService;
import com.koron.order.experiment.service.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ExperimentExecuteServiceImpl
 * @description
 * @Author zhouj
 * @Date 2021/9/16 8:53
 */
@Slf4j
@Service("experimentExecuteService")
public class ExperimentExecuteServiceImpl implements ExperimentExecuteService {

    @Autowired
    private OrderExecuteService orderExecuteService;

    @Autowired
    private OrderExecuteInfoService orderExecuteInfoService;

    @Autowired
    private OrderExecutePartService orderExecutePartService;

    @Autowired
    private ExperimentReadyService experimentReadyService;

    @Autowired
    private ExperimentEquipmentService equipmentService;

    @Autowired
    private ExperimentParamsService paramsService;

    @Autowired
    private ExperimentItemService itemService;

    @Autowired
    private ExperimentItemParamsService itemParamsService;

    @Autowired
    private ExperimentService experimentService;

    @Autowired
    ExperimentConvertor experimentConvertor;

    @Autowired
    OrderSignService orderSignService;

    @Autowired
    private WorkFlowHandler workFlowHandler;

    @Autowired
    private OrderInstructionService orderInstructionService;

    @Autowired
    ExperimentStandFeignService standFeignService;

    @Autowired
    ExperimentEquipmentFeignService equipmentFeignService;

    @Autowired
    ExperimentEquipmentSignService equipmentSignService;

    private ThreadLocal<KeyName> threadLocal = new ThreadLocal<>();

    @Autowired
    private AttachmentService attachmentService;

    @Autowired
    private ElectronicSignatureFeignService electronicSignatureFeignService;

    @Autowired
    private ConfigDetailService configDetailService;

    @Autowired
    private OrderDispatchService orderDispatchService;

    @Autowired
    OrgCacheUtils orgCacheUtils;

    @Override
    @TaskAnnotation("insertOrUpdate")
    public int insertOrUpdate(SessionFactory factory, ExperimentExecuteDto executeDto) {

        List<OrderExecute> orderExecuteList = new ArrayList<>();
        List<OrderExecutePart> orderExecutePartList = new ArrayList<>();

        String orderId = executeDto.getOrderId();

        //1.作业表单信息
        OperateFormVo operateFormVo = executeDto.getOperateFormVo();

        if (operateFormVo != null) {
            insertOrUpdateOperateForm(factory, operateFormVo);
        }

        //2.正常维护执行信息
        List<ExperimentExecuteInfoVo> experimentExecuteInfoVos = executeDto.getExperimentExecuteInfoVos();

        if (CollectionUtils.isNotEmpty(experimentExecuteInfoVos)) {
            experimentExecuteInfoVos.forEach(p -> {

                //2.1工单执行信息
                OrderExecute orderExecute = new OrderExecute();
                String executeId = StringUtils.isEmpty(orderExecute.getId()) ? CodeTools.getCode32() : orderExecute.getId();
                orderExecute.setId(executeId);
                orderExecute.setOrderId(orderId);
                orderExecuteList.add(orderExecute);

                //2.2工单执行备件信息
                List<OrderExecutePart> orderExecutePart = p.getOrderExecutePart();
                if (!CollectionUtils.isEmpty(orderExecutePart)) {
                    orderExecutePart.forEach(e -> {
                        e.setExecuteId(executeId);
                        e.setOrderId(orderId);
                    });
                    orderExecutePartList.addAll(p.getOrderExecutePart());
                }

            });
        }

        orderExecuteService.insertBatch(factory, orderExecuteList);
        orderExecutePartService.insertBatch(factory, orderExecutePartList);

        /*if (executeDto.getIsCommit()) {

            ExperimentPo experimentPo = experimentService.queryExperimentBeanById(factory, orderId);
            Assert.notNull(executeDto, "工单id无效");

            //启动工作流
            WorkflowProperties wfp = WorkflowProperties.init("experiment_wait_review");
            HashMap<String, String> map = new HashMap<>();
            //找到 工作负责人
            List<String> leaders = orderExecuteInfoService.querySubmitUserListByOrderId(factory, orderId, true);
            Assert.notEmpty(leaders, "没有找到工作负责人");
            String user = StringUtils.join(leaders.toArray(), ",");
            map.put("user", user);
            workFlowHandler.start(wfp, orderId, experimentPo.getCode(), map);
            //修改工单状态 执行中-->待审核
            experimentService.submitExperiment(factory, orderId, ExperimentStatus.WAIT_REVIEW.getStatus());
        }*/

        return 1;
    }

    @Override
    @TaskAnnotation("insertOrUpdateExecuteInfo")
    public String insertOrUpdateExecuteInfo(SessionFactory factory, ExperimentExecuteInfoVo experimentExecuteInfoVo) {

        //转换成工单执行信息
        OrderExecute orderExecute = experimentConvertor.voToOrderExecuteVo(experimentExecuteInfoVo);

        String orderExecuteId = orderExecute.getId();
        String orderId = orderExecute.getOrderId();

        if (StringUtils.isEmpty(orderExecuteId)) {
            orderExecute.setId(CodeTools.getCode32());
            orderExecuteService.insert(factory, orderExecute);
        } else {
            orderExecuteService.update(factory, orderExecute);
        }

        //工单执行备件信息
        List<OrderExecutePart> orderExecutePart = experimentExecuteInfoVo.getOrderExecutePart();
        orderExecutePart.forEach(p -> {
            p.setExecuteId(orderExecute.getId());
            p.setOrderId(orderId);
        });

        orderExecutePartService.insertBatch(factory, orderExecutePart);

        return orderExecuteId;
    }

    @Override
    public boolean deleteExecuteInfo(SessionFactory factory, String orderId, String orderExecuteId) {

        //根据工单id及工单执行id 删除执行信息
        orderExecuteService.deleteOrderExecute(factory, orderId, orderExecuteId);

        orderExecutePartService.deleteOrderExecutePart(factory, orderId, orderExecuteId);

        return true;
    }

    @Override
    @TaskAnnotation("insertOrUpdateOperateForm")
    public String insertOrUpdateOperateForm(SessionFactory factory, OperateFormVo operateFormVo) {

        List<ExperimentParamsPo> experimentParamsPos = new ArrayList<>();

        List<ExperimentReadyPo> experimentReadyPoList = operateFormVo.getExperimentReadyPoList();

        if (CollectionUtils.isEmpty(experimentReadyPoList)) {
            return null;
        }

        String experimentId = experimentReadyPoList.get(0).getExperimentId();

        ExperimentPo experimentPo1 = experimentService.queryExperimentBeanById(factory, experimentId);
        String signType = experimentPo1.getSignType();

        //1.2 作业表单-存在问题,改进建议 入主表
        String opinion = operateFormVo.getOpinion();
        String problem = operateFormVo.getProblem();

        ExperimentPo experimentPo = new ExperimentPo();
        experimentPo.setId(experimentId);
        experimentPo.setOpinion(opinion);
        experimentPo.setProblem(problem);
        experimentService.update(factory, experimentPo);

        //1.3 作业表单-作业准备 根据id更新确认状态值
        experimentReadyService.updateBatch(factory, experimentReadyPoList);

        //1.4 设备信息及下属项目
        List<ExperimentEquipmentVo> experimentEquipmentVoList = operateFormVo.getExperimentEquipmentVoList();

        if (!CollectionUtils.isEmpty(experimentEquipmentVoList)) {
            experimentEquipmentVoList.forEach(v -> {
                ExperimentEquipmentPo equipmentPo = experimentConvertor.voToExperimentEquipmentPo(v);
                //1.4.1 更新设备级  结论,是否合格
                equipmentService.update(factory, equipmentPo);

                //试验员列表信息
                List<ExperimentEquipmentSignPo> equipmentSignPos = v.getEquipmentSignPos();

                if (CollectionUtils.isNotEmpty(equipmentSignPos)) {
                    equipmentSignPos.forEach(p -> {
                        if (StringUtils.isEmpty(p.getId())) {
                            p.setId(CodeTools.getCode32());
                        }
                        p.setExperimentEquipmentId(equipmentPo.getId());
                    });
                    equipmentSignService.insertOrUpdateBatch(factory, equipmentSignPos);
                }

                //1.4.2 设备参数及环境参数
                List<ExperimentParamsPo> deviceParams = v.getDeviceParams();
                List<ExperimentParamsPo> envParams = v.getEnvParams();
                experimentParamsPos.addAll(deviceParams);
                experimentParamsPos.addAll(envParams);
                paramsService.insertOrUpdateBatch(factory, experimentParamsPos);

                //1.4.3 (作业过程)项目
                List<ExperimentItemVo> itemVos = v.getItemVos();

                //处理一下作业项目 将子项目列表平铺在第一层
                List<ExperimentItemVo> res = new ArrayList<>();
                dealItemBeanVoList(res, itemVos);

                res.forEach(p -> {
                    //1.4.3.1 项目确认及备注
                    ExperimentItemPo experimentItemPo = experimentConvertor.voToExperimentItemBean(p);
                    itemService.update(factory, experimentItemPo);

                    List<ExperimentItemParamsPo> itemParamsBeanList = p.getItemParamsBeanList();
                    List<OrderSignBean> orderSignBeanList = p.getOrderSignBeanList();
                    //1.4.3.2 项目参数
                    if (CollectionUtils.isNotEmpty(itemParamsBeanList)) {
                        itemParamsService.insertOrUpdateBatch(factory, itemParamsBeanList);
                    }
                    //1.4.3.3 工单签名
                    if (CollectionUtils.isNotEmpty(orderSignBeanList)) {
                        orderSignService.insertBatch(factory, orderSignBeanList);
                    }
                });
            });
        }

        return experimentId;
    }

    private void dealItemBeanVoList(List<ExperimentItemVo> list, List<ExperimentItemVo> itemBeanVoList) {

        if (CollectionUtils.isEmpty(itemBeanVoList)) {
            return;
        }

        for (ExperimentItemVo itemVo : itemBeanVoList) {

            List<ExperimentItemVo> experimentItemVos = itemVo.getExperimentItemVoList();
            itemVo.setExperimentItemVoList(null);
            list.add(itemVo);
            if (CollectionUtils.isNotEmpty(experimentItemVos)) {
                dealItemBeanVoList(list, experimentItemVos);
            }
        }

        return;
    }

    @Override
    @TaskAnnotation("deleteById")
    public int deleteById(SessionFactory factory, String id) {
        return 0;
    }

    @Override
    @TaskAnnotation("queryByOrderId")
    public OperateFormVo queryByOrderId(SessionFactory factory, String orderId) {

        OperateFormVo operateFormVo = new OperateFormVo();

        //1.根据工单id查询作业表单

        //1.1 作业准备
        List<ExperimentReadyPo> experimentReadyPoList = experimentReadyService.queryByOrderId(factory, orderId);
        //1.2 作业过程
        List<ExperimentEquipmentVo> experimentEquipmentVoList = equipmentService.queryByOrderId(factory, orderId);

        //1.3 作业指导书
        List<OrderInstructionBean> orderInstructionBeans = orderInstructionService.queryByBizId(factory, orderId);

        operateFormVo.setExperimentReadyPoList(experimentReadyPoList);
        operateFormVo.setExperimentEquipmentVoList(experimentEquipmentVoList);
        operateFormVo.setOrderInstructionBeanList(orderInstructionBeans);

        ExperimentPo experimentPo = experimentService.queryExperimentBeanById(factory, orderId);

        operateFormVo.setOpinion(experimentPo.getOpinion());
        operateFormVo.setProblem(experimentPo.getProblem());

        return operateFormVo;

    }

    @Override
    @TaskAnnotation("queryReadyByOrderId")
    public List<ExperimentReadyPo> queryReadyByOrderId(SessionFactory factory, String orderId) {
        return experimentReadyService.queryByOrderId(factory, orderId);
    }

    @Override
    @TaskAnnotation("queryInstructionByOrderId")
    public List<OrderInstructionBean> queryInstructionByOrderId(SessionFactory factory, String orderId) {
        return orderInstructionService.queryByBizId(factory, orderId);
    }

    @Override
    @TaskAnnotation("queryEquipmentVoByOrderId")
    public List<ExperimentEquipmentVo> queryEquipmentVoByOrderId(SessionFactory factory, String orderId) {
        return equipmentService.queryByOrderId(factory, orderId);
    }

    @Override
    @TaskAnnotation("queryEquipmentBeanListByOrderId")
    public List<ExperimentEquipmentPo> queryEquipmentBeanListByOrderId(SessionFactory factory, String orderId) {
        ExperimentEquipmentPo experimentEquipmentPo = new ExperimentEquipmentPo();
        experimentEquipmentPo.setExperimentId(orderId);
        return equipmentService.queryList(factory, experimentEquipmentPo);
    }

    @Override
    @TaskAnnotation("queryExperimentParamsByEqId")
    public ExperimentEquipmentVo queryExperimentParamsByEqId(SessionFactory factory, String orderId, String experimentEquipId) {

        ExperimentEquipmentVo experimentEquipmentVo = new ExperimentEquipmentVo();

        List<ExperimentParamsPo> paramsPos = paramsService.queryByEquipmentId(factory, orderId, experimentEquipId);

        if (CollectionUtils.isEmpty(paramsPos)) {
            return null;
        }

        List<ExperimentParamsPo> envList = paramsPos.stream().filter(s -> ParamType.ENVIRONMENT.equals(s.getType())).collect(Collectors.toList());
        List<ExperimentParamsPo> deviceList = paramsPos.stream().filter(s -> ParamType.EQUIPMENT.equals(s.getType())).collect(Collectors.toList());

        experimentEquipmentVo.setDeviceParams(deviceList);
        experimentEquipmentVo.setEnvParams(envList);

        return experimentEquipmentVo;
    }

    @Override
    @TaskAnnotation("queryExperimentItemByEqId")
    public List<ExperimentItemVo> queryExperimentItemByEqId(SessionFactory factory, String orderId, String experimentEquipId) {
        return itemService.queryByEquipmentId(factory, orderId, experimentEquipId);
    }

    @Override
    @TaskAnnotation("queryAttachmentListByOrderId")
    public List<Attachment> queryAttachmentListByOrderId(SessionFactory factory, String orderId) {

        //根据工单id查询已经签名完成的子业务id
        ExperimentEquipmentSignPo signPo = new ExperimentEquipmentSignPo();
        signPo.setExperimentId(orderId);
        List<ExperimentEquipmentSignPo> experimentEquipmentSignPos = equipmentSignService.queryList(factory, signPo);

        if (CollectionUtils.isEmpty(experimentEquipmentSignPos)) {
            return new ArrayList<>();
        }

        List<String> experimentEquipmentIds = experimentEquipmentSignPos.stream().map(ExperimentEquipmentSignPo::getExperimentEquipmentId).distinct().collect(Collectors.toList());

        experimentEquipmentSignPos.forEach(p -> {
            if (p.getSign() == 0) {
                experimentEquipmentIds.remove(p.getExperimentEquipmentId());
            }
        });

        if (CollectionUtils.isNotEmpty(experimentEquipmentIds)) {
            List<Attachment> list = new ArrayList<>();
            experimentEquipmentIds.forEach(p -> {
                List<Attachment> attachmentList = attachmentService.getAttachmentListByBusinessIdWithTypeWithSubBusinessId(orderId, null, p);
                list.addAll(attachmentList);
            });
            return list;
        }
        return new ArrayList<>();
    }

    @Override
    @TaskAnnotation("updateExperimentReady")
    public int updateExperimentReady(SessionFactory factory, ExperimentReadyPo experimentReadyPo) {
        //主要是更新确认状态
        return experimentReadyService.update(factory, experimentReadyPo);
    }

    @Override
    @TaskAnnotation("updateExperimentItemVo")
    public int updateExperimentItemVo(SessionFactory factory, ExperimentItemVo experimentItemVo) {

        //设备下-维护项目
        ExperimentItemPo experimentItemPo = experimentConvertor.voToExperimentItemBean(experimentItemVo);
        //主要是修改状态,备注
        itemService.update(factory, experimentItemPo);

        /*List<ExperimentItemParamsBean> itemParamsBeanList = experimentItemVo.getItemParamsBeanList();
        //先删除当前项目数据记录项列表,再插入
        itemParamsService.insertBatch(factory, itemParamsBeanList);

        List<OrderSignBean> orderSignBeanList = experimentItemVo.getOrderSignBeanList();
        //先删除当前项目签名人列表,再插入
        orderSignService.insertBatch(factory, orderSignBeanList);*/

        return 1;
    }

    @Override
    @TaskAnnotation("updateExperimentItem")
    public int updateExperimentItem(SessionFactory factory, ExperimentItemPo experimentItemPo) {

        //主要是修改状态,备注
        itemService.update(factory, experimentItemPo);

        return 1;
    }

    @Override
    @TaskAnnotation("updateExperimentItemParams")
    public int updateExperimentItemParams(SessionFactory factory, ExperimentItemParamsPo itemParamsBean) {
        //主要更新参数值
        return itemParamsService.update(factory, itemParamsBean);
    }

    @Override
    @TaskAnnotation("insertOrderSignInfo")
    public int insertOrderSignInfo(SessionFactory factory, OrderSignBean orderSignBean) {
        //新增签名人
        return orderSignService.insert(factory, orderSignBean);
    }

    @Override
    @TaskAnnotation("deleteOrderSignInfo")
    public int deleteOrderSignInfo(SessionFactory factory, String orderSignId) {
        //删除签名人记录
        return orderSignService.deleteById(factory, orderSignId);
    }

    @Override
    @TaskAnnotation("updateExperimentInfo")
    public int updateExperimentInfo(SessionFactory factory, ExperimentPo experimentPo) {
        //主要更新改进建议和存在问题
        return experimentService.update(factory, experimentPo);
    }

    @Override
    @TaskAnnotation("updateExperimentEquipmentInfo")
    public int updateExperimentEquipmentInfo(SessionFactory factory, ExperimentEquipmentPo equipmentPo) {
        return equipmentService.update(factory, equipmentPo);
    }

    @Override
    @TaskAnnotation("updateExperimentParamsPo")
    public int updateExperimentParamsPo(SessionFactory factory, ExperimentParamsPo experimentParamsPo) {
        return paramsService.update(factory, experimentParamsPo);
    }

    @Override
    @TaskAnnotation("generateStand")
    public boolean generateStand(SessionFactory factory, String orderId) {

        ExperimentEquipmentPo experimentEquipmentPo = new ExperimentEquipmentPo();
        experimentEquipmentPo.setExperimentId(orderId);
        List<ExperimentEquipmentPo> experimentEquipmentPos = equipmentService.queryList(factory, experimentEquipmentPo);

        if (CollectionUtils.isEmpty(experimentEquipmentPos)) {
            return false;
        }

        List<ExperimentDTO> experimentDtos = new ArrayList<>();
        List<ExperimentParamsPo> experimentParamsPos = new ArrayList<>();
        List<ExperimentItemPo> experimentItems = new ArrayList<>();
        List<ExperimentItemParamsPo> experimentItemParams = new ArrayList<>();

        experimentEquipmentPos.forEach(p -> {

            List<ExperimentDTO> experimentDtosTmp = new ArrayList<>();
            List<ExperimentParamsPo> experimentParamsPosTmp = new ArrayList<>();
            List<ExperimentItemPo> experimentItemsTmp = new ArrayList<>();
            List<ExperimentItemParamsPo> experimentItemParamsTmp = new ArrayList<>();

            String experimentId = p.getExperimentId();
            String eqid = p.getId();
            String equipmentId = p.getEquipmentId();
            String standardId = p.getStandardId();
            Response<ExperimentDTO> rsp = standFeignService.select(standardId);
            if (rsp.getCode() == HttpStatus.OK.value()) {
                ExperimentDTO data = rsp.getData();

                dealExperimentDTOS(data, experimentParamsPosTmp, experimentItemsTmp, experimentItemParamsTmp);

                //处理数据
                //项目
                experimentItemsTmp.forEach(v -> {
                    v.setEquipmentId(equipmentId);
                    v.setExperimentEquipId(eqid);
                    v.setExperimentId(experimentId);
                });
                //项目参数
                experimentItemParamsTmp.forEach(v -> {
                    v.setEquipmentId(equipmentId);
                    v.setExperimentEquipId(eqid);
                    v.setExperimentId(experimentId);
                });
                //设备环境参数
                experimentParamsPosTmp.forEach(v -> {
                    v.setEquipmentId(equipmentId);
                    v.setExperimentEquipmentId(eqid);
                    v.setExperimentId(experimentId);
                });

                experimentParamsPos.addAll(experimentParamsPosTmp);
                experimentItems.addAll(experimentItemsTmp);
                experimentItemParams.addAll(experimentItemParamsTmp);

            }
        });

        //各自入库
        paramsService.insertBatch(factory, experimentParamsPos);
        itemService.insertBatch(factory, experimentItems);

        itemParamsService.deleteByExperimentId(factory, orderId);
        itemParamsService.insertBatch(factory, experimentItemParams);

        //dealExperimentDTOS(experimentDTOS, experimentItems, experimentItemParams);

        return true;
    }

    /*
     * 功能描述
     * @author zhouj
     * @description 获取实验报告数据
     * @date 2021/10/15 14:11
     * @param [factory, experimentEquipmentId]
     * @return java.util.List
     */
    @Override
    @TaskAnnotation("getExperimentData")
    public Map<String, String> getExperimentData(SessionFactory factory, String experimentEquipmentId) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        List<FiledDescriptDto> filedDescriptDtos = getExperimentDataJson(factory, experimentEquipmentId);

        Map<String, String> describe = new HashMap<>();

        if (!CollectionUtils.isEmpty(filedDescriptDtos)) {
            filedDescriptDtos.forEach(p -> {
                describe.put(p.getFieldCode(), p.getFieldValue());
            });
        }

        return describe;

    }

    /*
     * 功能描述
     * @author zhouj
     * @description 获取试验报告--json
     * @date 2021/10/15 14:11
     * @param [factory, experimentEquipmentId]
     * @return java.util.List
     */
    @Override
    @TaskAnnotation("getExperimentDataJson")
    public List<FiledDescriptDto> getExperimentDataJson(SessionFactory factory, String experimentEquipmentId) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        try {
            //通过试验工单设备id 查询数据json
            List<ExperimentEquipmentVo> experimentEquipmentVos = equipmentService.queryByExperimentEquipmentId(factory, experimentEquipmentId);

            if (CollectionUtils.isEmpty(experimentEquipmentVos)) {
                return null;
            }
            ExperimentEquipmentVo experimentEquipmentVo = experimentEquipmentVos.get(0);

            List<ExperimentEquipmentSignPo> experimentEquipmentSignPos = equipmentSignService.queryByExperimentEquipmentId(factory, experimentEquipmentVo.getId());

            if (CollectionUtils.isNotEmpty(experimentEquipmentSignPos)) {
                List<ExperimentEquipmentSignPo> signPos = experimentEquipmentSignPos;
                if (CollectionUtils.isNotEmpty(signPos)) {
                    String experimenter = signPos.stream().map(ExperimentEquipmentSignPo::getAccount).collect(Collectors.joining(","));
                    String experimenterName = signPos.stream().map(ExperimentEquipmentSignPo::getAccount).collect(Collectors.joining(","));
                    StringBuilder sb = new StringBuilder();
                    String space = "                ";
                    for (int i = 0; i < signPos.size(); i++) {
                        if (i > 0 && i % 3 == 0) {
                            sb.append("\n");
                        }
                        sb.append(space);
                        sb.append("/");
                        sb.append(signPos.get(i).getName());

                    }
                    experimentEquipmentVo.setExperimenterName(sb.toString());

                }
            }

            Map<String, String> fieldDescriptMap = new HashMap<>();

            //利用反射拿到配置的注释
            Field[] allFields = FieldUtils.getAllFields(ExperimentEquipmentVo.class);
            for (Field allField : allFields) {
                allField.setAccessible(true);
                Class<? extends Field> aClass = allField.getClass();
                if (!allField.getType().equals(List.class)) {
                    ApiModelProperty annotation = allField.getAnnotation(ApiModelProperty.class);
                    if (!Objects.isNull(annotation)) {
                        String name = allField.getName();
                        String value = annotation.value();
                        fieldDescriptMap.put(name, value);
                    }
                }
            }

            List<FiledDescriptDto> filedDescriptDtos = new ArrayList<>();

            //转换数据
            Map<String, String> describe = BeanUtils.describe(experimentEquipmentVo);

            //将是否合格转化为字典
            String passStatus = describe.get("passStatus");
            if (StringUtils.isNotEmpty(passStatus)) {
                describe.put("passStatus", "1".equals(passStatus) ? "合格" : "不合格");
            }

            describe.remove("class");
            describe.remove("itemVos");
            describe.remove("envParams");
            describe.remove("deviceParams");

            //加入页尾
            String reportFooter = getReportFooter(experimentEquipmentId);
            filedDescriptDtos.add(new FiledDescriptDto("reportFooter", "报告文件页尾", reportFooter));

            if (!MapUtils.isEmpty(describe)) {
                for (String s : describe.keySet()) {
                    String fieldDes = fieldDescriptMap.get(s);
                    filedDescriptDtos.add(new FiledDescriptDto(s, fieldDes == null ? s : fieldDes, describe.get(s)));
                }
            }

            String equipmentId = experimentEquipmentVo.getEquipmentId();
            //equipmentId --> 调用设备接口查询设备基础参数及参数值
            Response<JSONObject> equipRsp = equipmentFeignService.getById(equipmentId);

            if (equipRsp.getCode() == HttpStatus.OK.value()) {
                JSONObject data = equipRsp.getData();
                String devName = data.getString("name");
                String devCode = data.getString("code");
                filedDescriptDtos.add(new FiledDescriptDto("devName", "设备名称", devName));
                filedDescriptDtos.add(new FiledDescriptDto("devCode", "设备code", devCode));
                JSONArray paramsList = data.getJSONArray("params");
                if (CollectionUtils.isNotEmpty(paramsList)) {
                    //取出参数值
                    for (Object o : paramsList) {
                        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(o));
                        String paramName = jsonObject.getString("paramName");
                        String paramValue = jsonObject.getString("paramValue");
                        String paramResult = jsonObject.getString("paramResult");
                        filedDescriptDtos.add(new FiledDescriptDto(getKeyName(), paramName, paramValue));
                    }
                    threadLocal.get().setNextSuffix();
                }
            }

            //设备及环境参数
            List<ExperimentParamsPo> paramsPos = new ArrayList<>();
            List<ExperimentParamsPo> envParams = experimentEquipmentVo.getEnvParams();
            List<ExperimentParamsPo> deviceParams = experimentEquipmentVo.getDeviceParams();
            paramsPos.addAll(envParams);
            paramsPos.addAll(deviceParams);
            if (!CollectionUtils.isEmpty(paramsPos)) {
                paramsPos.forEach(p -> {
                    filedDescriptDtos.add(new FiledDescriptDto(getKeyName(), p.getName(), StringUtils.isEmpty(p.getUnit()) ? p.getValue() : p.getValue() + p.getUnit()));
                });
                threadLocal.get().setNextSuffix();
            }

            //作业项目及参数项
            List<ExperimentItemVo> itemVos = experimentEquipmentVo.getItemVos();

            List<ExperimentItemPo> experimentItemsTmp = new ArrayList<>();
            List<ExperimentItemParamsPo> experimentItemParamsTmp = new ArrayList<>();

            //处理作业项目及参数项

            dealExperimentItemVoS(null, itemVos, experimentItemsTmp, experimentItemParamsTmp);

            if (CollectionUtils.isNotEmpty(experimentItemParamsTmp)) {
                experimentItemParamsTmp.forEach(v -> {
                    String keyName = getKeyName();
                    filedDescriptDtos.add(new FiledDescriptDto(keyName, v.getName() + keyName, v.getValue()));
                });
                threadLocal.get().setNextSuffix();
            }

            //处理一下filedDescriptDtos value为空设置\

            filedDescriptDtos.forEach(p -> {
                if (StringUtils.isEmpty(p.getFieldValue())) {
                    p.setFieldValue("/");
                }
            });

            return filedDescriptDtos;

        } finally {
            threadLocal.remove();
        }

    }

    /**
     * 通过试验工单id获取文件的页尾
     * 规则 前缀-设备管理单位+标准名称-试验单位英文缩写-yyyyMMdd-001
     */
    private String getReportFooter(String experimentEquipmentId) {

        try (SessionFactory factory = new SessionFactory()) {
            factory.setDbEnv(ThreadLocalContext.get().getCurrDs());
            StringBuffer sb = new StringBuffer();

            ExperimentEquipmentPo equipmentPo = equipmentService.queryById(factory, experimentEquipmentId);

            String experimentId = equipmentPo.getExperimentId();

            //设备关联的标准名称
            String standardName = equipmentPo.getStandardName();

            ExperimentPo experimentPo = experimentService.queryExperimentBeanById(factory, experimentId);

            //设备管理单位名称
            String deptManageName = experimentPo.getDeptManageName();

            //调用配置项service时需要指定数据源
            factory.setDbEnv(null);
            ConfigDetail configDetail = configDetailService.getByClassifyCodeAndCodeAndAppidAndKey(factory, "order", "experiment_report", ThreadLocalContext.getApp().getId(), "prefix");
            factory.setDbEnv(ThreadLocalContext.get().getCurrDs());
            //配置好的报告页尾前缀
            String prefix = configDetail.getValue();

            sb.append(prefix);
            sb.append("-");
            sb.append(deptManageName);
            sb.append(standardName);
            sb.append("-");

            //获取试验单位的组织简称
            OrderDispatch orderDispatch = orderDispatchService.queryByOrderId(factory, experimentId);
            String deptWork = orderDispatch.getDeptWork();
            //根据组织查询组织的简称
            OrgBean orgBean = orgCacheUtils.getOrgById(deptWork);
            String simpleEn = orgBean.getPrefix();
            sb.append(simpleEn);
            sb.append("-");
            sb.append(DateUtils.getString(new Date(), "yyyyMMdd"));
            //以年为单位计数
            String experimentReportCode = CommonCodeTools.getExperimentReportCode(simpleEn, 6);
            sb.append("-");
            sb.append(Integer.parseInt(experimentReportCode.substring(experimentReportCode.length() - 6)));

            return sb.toString();
        }

    }

    /*
     * 功能描述
     * @author zhouj
     * @description 通过试验标准(标准绑定了所属设备分类,设备分类绑定了具体的设备) 获取试验报告json
     * @date 2021/10/15 14:11
     * @param [factory, experimentEquipmentId]
     * @return java.util.List
     */
    @Override
    @TaskAnnotation("getExperimentDataJsonFromStandard")
    public List<FiledDescriptDto> getExperimentDataJsonFromStandard(SessionFactory factory, String standardId) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        try {
            //通过试验工单设备id 查询数据json
            Map<String, String> fieldDescriptMap = new HashMap<>();

            //利用反射拿到配置的注释
            Field[] allFields = FieldUtils.getAllFields(ExperimentEquipmentVo.class);
            for (Field allField : allFields) {
                allField.setAccessible(true);
                Class<? extends Field> aClass = allField.getClass();
                if (!allField.getType().equals(List.class)) {
                    ApiModelProperty annotation = allField.getAnnotation(ApiModelProperty.class);
                    if (!Objects.isNull(annotation)) {
                        String name = allField.getName();
                        String value = annotation.value();
                        fieldDescriptMap.put(name, value);
                    }
                }
            }

            List<FiledDescriptDto> filedDescriptDtos = new ArrayList<>();

            //转换数据
            Map<String, String> describe = BeanUtils.describe(new ExperimentEquipmentVo());

            describe.remove("class");
            describe.remove("itemVos");
            describe.remove("envParams");
            describe.remove("deviceParams");

            //加入页尾
            filedDescriptDtos.add(new FiledDescriptDto("reportFooter", "报告文件页尾", null));

            if (!MapUtils.isEmpty(describe)) {
                for (String s : describe.keySet()) {
                    String fieldDes = fieldDescriptMap.get(s);
                    filedDescriptDtos.add(new FiledDescriptDto(s, fieldDes == null ? s : fieldDes, describe.get(s)));
                }
            }

            filedDescriptDtos.add(new FiledDescriptDto("devName", "设备名称", null));
            filedDescriptDtos.add(new FiledDescriptDto("devCode", "设备code", null));

            List<ExperimentParamsPo> experimentParamsPosTmp = new ArrayList<>();
            List<ExperimentItemPo> experimentItemsTmp = new ArrayList<>();
            List<ExperimentItemParamsPo> experimentItemParamsTmp = new ArrayList<>();

            //根据试验标准id找到所属设备分类 -- 根据设备分类id找到设备基础参数及技术参数
            Response<ExperimentDTO> res = standFeignService.select(standardId);
            ExperimentDTO experimentDTO = res.getData();
            //设备分类ID
            String typeId = experimentDTO.getTypeId();

            Response<BaseTypeDTO> baseTypeDTOResponse = standFeignService.selectDetailOne(typeId);

            if (baseTypeDTOResponse.getCode() == HttpStatus.OK.value()) {
                BaseTypeDTO baseTypeDTO = baseTypeDTOResponse.getData();
                Collection<TypeGroupParams> typeGroupParamsList = baseTypeDTO.getTypeGroupParamsList();
                for (TypeGroupParams typeGroupParams : typeGroupParamsList) {
                    filedDescriptDtos.add(new FiledDescriptDto(getKeyName(), typeGroupParams.getParamName(), null));
                }

                Collection<TypeParams> typeParamsList = baseTypeDTO.getTypeParamsList();

                for (TypeParams typeParams : typeParamsList) {
                    filedDescriptDtos.add(new FiledDescriptDto(getKeyName(), typeParams.getParamName(), null));
                }
                threadLocal.get().setNextSuffix();

            }

            //设备及环境参数
            List<ExperimentParams> paramsPos = new ArrayList<>();
            List<ExperimentParams> envParams = experimentDTO.getEnvParams();
            List<ExperimentParams> deviceParams = experimentDTO.getDeviceParams();
            paramsPos.addAll(envParams);
            paramsPos.addAll(deviceParams);
            if (!CollectionUtils.isEmpty(paramsPos)) {
                paramsPos.forEach(p -> {
                    filedDescriptDtos.add(new FiledDescriptDto(getKeyName(), p.getName(), null));
                });
                threadLocal.get().setNextSuffix();
            }

            //作业项目及参数项
            dealExperimentDTOS(experimentDTO, experimentParamsPosTmp, experimentItemsTmp, experimentItemParamsTmp);

            if (CollectionUtils.isNotEmpty(experimentItemParamsTmp)) {
                experimentItemParamsTmp.forEach(v -> {
                    String keyName = getKeyName();
                    filedDescriptDtos.add(new FiledDescriptDto(keyName, v.getName() + keyName, v.getValue()));
                });
                threadLocal.get().setNextSuffix();
            }

            return filedDescriptDtos;

        } finally {
            threadLocal.remove();
        }

    }

    @Override
    @TaskAnnotation("electronicSignatureCallback")
    public Response electronicSignatureCallback(SessionFactory factory, String experimentEquipmentId, String documentId, String tenantName, String contact, String type, String signStatus) {

        //电子签章回调  experimentEquipmentId+contact+signStatus
        log.info("电子签章回调 业务id:{},签署人:{},签署人手机号:{},type:{},返回状态:{}", experimentEquipmentId, tenantName, contact, type, signStatus);
        ExperimentEquipmentSignPo signPo = new ExperimentEquipmentSignPo();

        if (StringUtils.isEmpty(experimentEquipmentId)) {
            return Response.fail("业务id不能为空");
        }

        if (StringUtils.equalsIgnoreCase(type, ElectronicSignatureStatus.INTERNAL_FLOW.name())) {
            //只有内部流程回调 才更新
            signPo.setExperimentEquipmentId(experimentEquipmentId);
            signPo.setOperationTime(new Date());
            signPo.setPhone(contact);
            signPo.setName(tenantName);
            signPo.setSign(1);

            equipmentSignService.updateByExperimentEquipmentId(factory, signPo);
        }

        if (StringUtils.equalsIgnoreCase(type, ElectronicSignatureStatus.CONTRACT_COMPLETE.name())) {
            //签署完成（合同签署完成）-->更新签名后文件覆盖原来文件
            Response<String> res = electronicSignatureFeignService.updateAttachMent(documentId);
            if (res.getCode() == 200) {
                log.info("更新签名文件成功:{}", res.getData());
            }
        }
        return Response.ok("回调更新签名状态成功");
    }

    synchronized String getKeyName() {

        KeyName keyName = threadLocal.get();
        if (Objects.isNull(keyName)) {
            KeyName keyName1 = new KeyName();
            keyName1.init();
            threadLocal.set(keyName1);
            return keyName1.getCurr();
        }
        keyName.setNextSort();
        return keyName.getCurr();
    }

    //标准处理
    private void dealExperimentDTOS(ExperimentDTO experimentDTO, List<ExperimentParamsPo> experimentParamsPos, List<ExperimentItemPo> experimentItems, List<ExperimentItemParamsPo> experimentItemParams) {
        if (experimentDTO == null) {
            return;
        }

        List<ExperimentItemDTO> itemDTOs = experimentDTO.getItemDTOs();
        dealExperimentItemDTOS(null, itemDTOs, experimentItems, experimentItemParams);

        //处理设备及环境参数
        List<ExperimentParams> deviceParams = experimentDTO.getDeviceParams();
        List<ExperimentParams> envParams = experimentDTO.getEnvParams();

        deviceParams.forEach(p -> {
            ExperimentParamsPo experimentParamsPo = experimentConvertor.beanToBean(p);
            experimentParamsPo.setId(null);
            experimentParamsPos.add(experimentParamsPo);
        });

        envParams.forEach(p -> {
            ExperimentParamsPo experimentParamsPo = experimentConvertor.beanToBean(p);
            experimentParamsPo.setId(null);
            experimentParamsPos.add(experimentParamsPo);
        });

    }


    //项目处理
    private void dealExperimentItemDTOS(String parentId, List<ExperimentItemDTO> experimentItemDtos, List<ExperimentItemPo> experimentItems, List<ExperimentItemParamsPo> experimentItemParams) {

        if (CollectionUtils.isEmpty(experimentItemDtos)) {
            return;
        }
        experimentItemDtos.forEach(p -> {

            ExperimentItemPo experimentItem = experimentConvertor.dtoToBean(p);
            experimentItem.setId(CodeTools.getCode32());
            experimentItem.setParentId(parentId);
            experimentItems.add(experimentItem);
            List<ExperimentItemParams> itemParams = p.getItemParams();
            itemParams.forEach(v -> {
                ExperimentItemParamsPo itemParamsBean = experimentConvertor.beanToBean(v);
                itemParamsBean.setItemId(experimentItem.getId());
                itemParamsBean.setId(null);
                experimentItemParams.add(itemParamsBean);
            });

            List<ExperimentItemDTO> children = p.getChildren();
            dealExperimentItemDTOS(experimentItem.getId(), children, experimentItems, experimentItemParams);
        });

    }

    //项目处理
    private void dealExperimentItemVoS(String parentId, List<ExperimentItemVo> experimentItemVos, List<ExperimentItemPo> experimentItems, List<ExperimentItemParamsPo> experimentItemParams) {

        if (CollectionUtils.isEmpty(experimentItemVos)) {
            return;
        }
        experimentItemVos.forEach(p -> {

            ExperimentItemPo experimentItem = experimentConvertor.voToExperimentItemBean(p);
            experimentItems.add(experimentItem);
            List<ExperimentItemParamsPo> itemParams = p.getItemParamsBeanList();
            itemParams.forEach(v -> {
                experimentItemParams.add(v);
            });

            List<ExperimentItemVo> children = p.getExperimentItemVoList();
            dealExperimentItemVoS(experimentItem.getId(), children, experimentItems, experimentItemParams);
        });

    }


}
